package com.share.tools;

import com.share.domain.Person;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author caifan
 * @date 2019/10/20
 */
public class Object2MapUtils {

    public static void main(String[] args) throws NoSuchFieldException, Exception {
        Person person = new Person();
        person.setId(1);
        person.setName("张三");
        Class clazz = person.getClass();

        object2Map(person);

        Person person1 = new Person();
        Map<String, String> map = new HashMap<>();
        map.put("id", "1");
        map.put("name", "zhangsan");
        map.put("age", "22");
        map.put("birth", "2000-10-10 10:10:10");
        map.put("height", "190.00");
        map2Object(person1, map);
        System.out.println(person1);
    }


    private static Field getFieldByName(Class clz, String fieldName) throws NoSuchFieldException, SecurityException {
        Field[] declaredFields = clz.getDeclaredFields();
        List<Field> asList = Arrays.asList(declaredFields);
        for (Field field : asList) {
            if (field.getName().equals(fieldName)) {
                return clz.getDeclaredField(fieldName);
            }
        }
        return getFieldByName(clz.getSuperclass(), fieldName);
    }

    private static Map<String, Object> object2Map(Object object) throws Exception {
        BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        Map<String, Object> map = new HashMap<>();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            System.out.println(propertyDescriptor.getName());
            Method method = propertyDescriptor.getReadMethod();
            System.out.println(method.invoke(object));
            map.put(propertyDescriptor.getName(), method.invoke(object));
        }
        return map;
    }

    private static void map2Object(Object object, Map<String, String> map) throws Exception {
        BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            if (null != map.get(propertyDescriptor.getName())) {
                Method method = propertyDescriptor.getWriteMethod();
                Class<?> propertyType = propertyDescriptor.getPropertyType();
                if (propertyType.getSimpleName().equals("String")) {
                    method.invoke(object, map.get(propertyDescriptor.getName()));
                } else if (propertyType.getSimpleName().equals("BigDecimal")) {
                    method.invoke(object, BigDecimal.valueOf(Double.valueOf(map.get(propertyDescriptor))));
                } else if (propertyType.getSimpleName().equals("Double")) {
                    method.invoke(object, Double.valueOf(map.get(propertyDescriptor.getName())));
                } else if (propertyType.getSimpleName().equals("Boolean")) {
                    method.invoke(object, Boolean.parseBoolean(map.get(propertyDescriptor.getName())));
                } else if (propertyType.getSimpleName().equals("Integer")) {
                    method.invoke(object, Integer.parseInt(map.get(propertyDescriptor.getName()).trim()));
                }

            }
        }
    }

}
